package com.lt.common;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;


/**
 * 在进行java编程是有时需要进行 基本类型到byte[]数据的转化。
 * 在进行与c和C++的通信时我们有时也需要将float，long，int，char等数据转换成byte通过socket通信
 * 等发送到C或C++,然后C和C++再将byte[]转换成float，long，int。
 * 下面这个类是个工具类，除最后两个方法仅能用在java和java通信使用，其它可以用作与c进行通信时转换数据使用。
 */
public class TypeHelper {
    private static TypeHelper instance;

    private TypeHelper() {

    }

    public static TypeHelper getInstance() {
        if (instance == null) {
            synchronized (TypeHelper.class) {
                instance = new TypeHelper();
            }
        }
        return instance;
    }

    /**
     * byte转int(考虑到byte可能会有超出范围的情况)
     * 跟其他语言对接通讯接口过程中，因java是有符号的，所有一个字节可能会有超过的情况，通讯端需要做特殊的处理
     */
    public Integer byteToInteger(Byte b) {
        return 0xff & b;
    }

    public static byte[] int2Byte(int l) {
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = Integer.valueOf(l).byteValue();
            l = l >> 8;
        }
        return b;
    }

    /**
     * 整数转C++存放格式的字节数组
     *
     * @param v int
     * @return byte[]
     */

    public static byte[] int2Byte4C(int v) {
        byte[] b = new byte[4];
        //注意,不是java中的顺序的 b[0],b[1],b[2],b[3]
        b[3] = (byte) ((v >>> 24) & 0xFF);
        b[2] = (byte) ((v >>> 16) & 0xFF);
        b[1] = (byte) ((v >>> 8) & 0xFF);
        b[0] = (byte) ((v) & 0xFF);
        return b;
    }

    public static int byte2Int(byte[] b) {
        int l = 0;
        l = b[0];
        l &= 0xff;
        l |= ((int) b[1] << 8);
        l &= 0xffff;
        l |= ((int) b[2] << 16);
        l &= 0xffffff;
        l |= ((int) b[3] << 24);
        l &= 0xffffffff;
        return l;
    }


    public static byte[] longToByte(long l) {
        byte[] b = new byte[8];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Long(l).byteValue();
            l = l >> 8;
        }
        return b;
    }

    public static long byteToLong(byte[] b) {
        long l = 0;
        l |= (((long) b[7] & 0xff) << 56);
        l |= (((long) b[6] & 0xff) << 48);
        l |= (((long) b[5] & 0xff) << 40);
        l |= (((long) b[4] & 0xff) << 32);
        l |= (((long) b[3] & 0xff) << 24);
        l |= (((long) b[2] & 0xff) << 16);
        l |= (((long) b[1] & 0xff) << 8);
        l |= ((long) b[0] & 0xff);
        return l;
    }


    public static byte[] float2Byte(float f) {
        byte[] b = new byte[4];
        int l = Float.floatToIntBits(f);
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(l).byteValue();
            l = l >> 8;
        }
        return b;
    }

    public static float byte2Float(byte[] b) {
        int l = 0;
        l = b[0];
        l &= 0xff;
        l |= ((int) b[1] << 8);
        l &= 0xffff;
        l |= ((int) b[2] << 16);
        l &= 0xffffff;
        l |= ((int) b[3] << 24);
        l &= 0xffffffffl;
        return Float.intBitsToFloat(l);
    }

    public static byte[] doubleToByte(double d) {
        byte[] b = new byte[8];
        long l = Double.doubleToLongBits(d);
        for (int i = 0; i < b.length; i++) {
            b[i] = new Long(l).byteValue();
            l = l >> 8;
        }
        return b;
    }


    public static char[] bytesToChars(byte[] bytes, int offset, int count) {
        char chars[] = new char[count];
        for (int i = 0; i < count; i++) {
            chars[i] = (char) bytes[i];
        }
        return chars;
    }

    public static byte[] charsToBytes(char[] chars, int offset, int count) {
        byte bytes[] = new byte[count];
        for (int i = 0; i < count; i++) {
            bytes[i] = (byte) chars[i];
        }
        return bytes;
    }

    public static byte[] floatToByte(float v) {
        ByteBuffer bb = ByteBuffer.allocate(4);
        byte[] ret = new byte[4];
        FloatBuffer fb = bb.asFloatBuffer();
        fb.put(v);
        bb.get(ret);
        return ret;
    }

    public static float byteToFloat(byte[] v) {
        ByteBuffer bb = ByteBuffer.wrap(v);
        FloatBuffer fb = bb.asFloatBuffer();
        return fb.get();
    }
}
